package com.leyantech.ecp.agenx.common.service;

import static com.leyantech.ecp.agenx.common.config.ConfigManager.checkLxySeat;
import static com.leyantech.ecp.agenx.common.config.ConfigManager.wholeLinkProductFuncEnabled;
import static com.leyantech.ecp.agenx.common.config.ConfigManager.wholeLinkProductList;
import static com.leyantech.ecp.agenx.common.config.ConfigManager.wholeLinkProductWhiteListStoreIdList;
import static com.leyantech.storehome.StoreSubscribeStatus.EXPIRED;
import static com.leyantech.storehome.StoreSubscribeStatus.TRIAL;
import static com.leyantech.storehome.StoreSubscribeStatus.VALID;

import com.leyantech.ecp.agenx.common.entity.AssistantSeatVO;
import com.leyantech.ecp.agenx.common.entity.EcpLxkProductSubscribeInfo;
import com.leyantech.ecp.agenx.common.entity.HelaKey;
import com.leyantech.ecp.agenx.common.entity.HelaStoreSubscribeDto;
import com.leyantech.ecp.agenx.common.entity.NormalAssistantDto;
import com.leyantech.ecp.agenx.common.entity.SalesInfo;
import com.leyantech.ecp.agenx.common.entity.SeatManagerInfo;
import com.leyantech.ecp.agenx.common.service.HelaService.HelaGetter;
import com.leyantech.ecp.agenx.common.utils.JsonUtils;

import com.google.common.collect.Sets;
import com.google.inject.Inject;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;

import java.util.Arrays;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * @author eahau, {@literal <eahau@foxmail.com>}
 * @date 2022-11-16.
 */
@Slf4j
public class StoreConfigService {

  static final Set<String> enableSubscribeStatus = Sets.newHashSet(VALID.name(), TRIAL.name());

  private final HelaService helaService;

  @Inject
  public StoreConfigService(HelaService helaService) {
    this.helaService = helaService;
  }

  public boolean isLxkSubscribe(String sid) {
    return HelaKey.ECP_LXK_PRODUCT_SUBSCRIBE_INFO.<EcpLxkProductSubscribeInfo>get(sid)
        .map(EcpLxkProductSubscribeInfo::getSubscribeStatus)
        .filter(VALID.name()::equals)
        .isPresent();

  }

  /**
   * 检查当前门店当前客服是否被禁用.
   *
   * @param storeId     门店id.
   * @param assistantId 客服id.
   * @return 是否禁用.
   */
  public boolean isAssistantForbidden(String storeId, String assistantId) {

    Optional<List<NormalAssistantDto>> assistantSeatListOpt = HelaKey.ENABLE_ASSISTANT.get(storeId);

    if (!assistantSeatListOpt.isPresent()) {
      log.warn("当前门店未配置客服列表：{}, aid:{}", storeId, assistantId);
      return true;
    }

    List<NormalAssistantDto> normalAssistantDtoList = assistantSeatListOpt.get();

    log.debug("checkAssistantIsForbidden| sid:{}, 查询到当前门店配置客服。：{}",
        storeId, JsonUtils.lazyToString(normalAssistantDtoList));

    for (NormalAssistantDto normalAssistantDto : normalAssistantDtoList) {
      if (Objects.equals(normalAssistantDto.getAssistantId(), assistantId)) {
        return false;
      }
    }

    return true;
  }

  static final List<HelaKey> helaKeys = Arrays
      .asList(HelaKey.ECP_SEAT_MANAGER_INFO, HelaKey.ECP_SHOP_VERSION, HelaKey.ENABLE_ASSISTANT);

  /**
   * 检查当前门店当前客服or设备号是否被禁用.
   */
  public boolean isAssistantForbidden(String storeId, String assistantId, String deviceNo) {

    final HelaGetter helaGetter = helaService.batchGetter(storeId, helaKeys);

    List<NormalAssistantDto> normalAssistantDtoList = helaGetter.get(HelaKey.ENABLE_ASSISTANT);
    if (CollectionUtils.isEmpty(normalAssistantDtoList)) {
      log.warn("当前门店未配置客服列表: {}, aid:{}", storeId, assistantId);
      return true;
    }

    List<String> aids = normalAssistantDtoList.stream()
        .map(NormalAssistantDto::getAssistantId)
        .collect(Collectors.toList());
    log.debug("isAssistantForbidden| sid:{}, 查询到当前门店配置客服。：{}", storeId, aids);
    if (CollectionUtils.isEmpty(aids)) {
      return true;
    }

    // 限制设备号（席位数）
    List<String> shopVersionList = helaGetter.get(HelaKey.ECP_SHOP_VERSION);

    SeatManagerInfo seatManagerInfo = helaGetter.get(HelaKey.ECP_SEAT_MANAGER_INFO);
    // 全链路产品时.
    if (CollectionUtils.isNotEmpty(shopVersionList)
        && seatManagerInfo != null
        && CollectionUtils.containsAny(shopVersionList, wholeLinkProductList.get())
        && (wholeLinkProductFuncEnabled.get()
        || wholeLinkProductWhiteListStoreIdList.get().contains(storeId))) {
      List<String> deviceNoList = seatManagerInfo.getDeviceNoList();
      log.debug("isAssistantForbidden| sid:{}, deviceNoList: {},deviceNo: {}",
          storeId, deviceNoList, deviceNo);
      // 当来自cem或者其他第三方合作方时，deviceNO 可能为null，不需要校验设备号.
      if ((StringUtils.isBlank(deviceNo) || deviceNoList.contains(deviceNo))
          && aids.contains(assistantId)) {
        return false;
      }
      log.warn("当前门店未授权该设备号: {}, deviceNo:{}", storeId, deviceNo);
    } else {
      return !aids.contains(assistantId);
    }

    return true;
  }

  /**
   * 检查当前门店当前客服是否被禁用.
   *
   * @param storeId     门店id.
   * @param assistantId 客服id.
   * @return 是否禁用.
   */
  public boolean isLxkAssistantForbidden(String storeId, String assistantId) {

    if (!checkLxySeat.get()) {
      // 是否需要验证lxk 坐席.
      return false;
    }

    Optional<List<AssistantSeatVO>> assistantSeatListOpt = HelaKey.ECP_LXK_ASSISTANT_LIST
        .get(storeId);

    if (!assistantSeatListOpt.isPresent()) {
      log.warn("当前门店未配置客服列表：{}, aid:{}", storeId, assistantId);
      return true;
    }

    List<AssistantSeatVO> normalAssistantDtoList = assistantSeatListOpt.get();

    log.info("checkLxkAssistantIsForbidden| sid:{}, 查询到当前门店配置客服。：{}",
        storeId, JsonUtils.lazyToString(normalAssistantDtoList));

    for (AssistantSeatVO normalAssistantDto : normalAssistantDtoList) {
      if (Objects.equals(normalAssistantDto.getAssistantId(), assistantId)) {
        return false;
      }
    }

    return true;
  }

  public boolean isSalesSwitchFlagOn(String sid) {
    Optional<SalesInfo> salesInfoOptional = HelaKey.ECP_SALES_INFO.get(sid);

    if (salesInfoOptional.isPresent()) {
      Boolean salesSwitchFlag = salesInfoOptional.get().getSalesSwitchFlag();
      log.info("sales switch flag from hela is: {} for storeId {}", salesSwitchFlag, sid);
      return salesSwitchFlag == null || salesSwitchFlag;
    }
    log.warn("no salesInfo found in hela for storeId: {}", sid);
    return true;
  }

  /**
   * 是否订阅.
   */
  public boolean isSubscribe(String sid) {
    final Optional<HelaStoreSubscribeDto> subscribeInfoOptional = HelaKey.ECP_STORE_SUBSCRIBE_INFO
        .get(sid);
    log.info("getSubscribeInfo 店铺有效信息 sid:{}, res:{}", sid, subscribeInfoOptional);
    if (subscribeInfoOptional.isPresent()) {
      HelaStoreSubscribeDto subscribeInfo = subscribeInfoOptional.get();
      if (StringUtils.isNotBlank(subscribeInfo.getSubscribeStatus()) && !enableSubscribeStatus
          .contains(subscribeInfo.getSubscribeStatus())) {
        if (EXPIRED.name().equals(subscribeInfo.getSubscribeStatus()) && !isSalesSwitchFlagOn(
            sid)) {
          //这里加一个特殊逻辑，如果店铺状态为过期，并且售卖限制开关为关的话，就放过拦截
          log.info("storeId: {} is expire, but salesSwitchFlag is false, let go", sid);
          return true;
        } else {
          //正常逻辑，只要店铺非有效或者非试用，就拦截
          log.info("storeId: {} is not valid or trial, intercept", sid);
          return false;
        }
      }
    } else {
      log.warn("当前店铺没有查到订阅信息.{}", sid);
      return false;
    }
    return true;
  }

}
